package ua.com.alus.resvac.crm.stripes.action.vacancy;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontValidate;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.UrlBinding;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import ua.com.alus.resvac.crm.domen.entities.City;
import ua.com.alus.resvac.crm.domen.entities.Vacancy;
import ua.com.alus.resvac.crm.domen.entities.VacancyFile;
import ua.com.alus.resvac.crm.services.spring.AccountService;
import ua.com.alus.resvac.crm.services.spring.BaseService;
import ua.com.alus.resvac.crm.services.spring.VacancyService;
import ua.com.alus.resvac.crm.stripes.base.BaseAction;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * Vacancy Action
 * Created by Usatov Alexey
 */
@UrlBinding("/vacancy/Vacancy.action")
public class VacancyAction extends BaseAction {
    private static final Logger LOGGER = Logger.getLogger(VacancyAction.class);

    public static final String VACANCY_UUID_PARAM = "vacancyUuid";
    public static final String CURRENT_CITY_ATTR = "currentCity";
    public static final String VACANCY_FILE_UUID_PARAM = "vacancyFileUuid";

    @SpringBean("/vacancy/vacancyService")
    private VacancyService vacancyService;

    @SpringBean("/base/baseService")
    private BaseService baseService;

    @SpringBean("/account/accountService")
    private AccountService accountService;

    private List<String> vacancyFilesUuid;

    @ValidateNestedProperties({
            @Validate(field = "fkProfAreaUuid", required = true),
            @Validate(field = "description", required = true),
            @Validate(field = "position", required = true),
            @Validate(field = "fkCityId", required = true),
            @Validate(field = "fkRegionId", required = true)
    })
    private Vacancy vacancy;

    private VacancyFile vacancyFile;

    public Vacancy getVacancy() {
        return vacancy;
    }

    public void setVacancy(Vacancy vacancy) {
        this.vacancy = vacancy;
    }

    public List<String> getVacancyFilesUuid() {
        return vacancyFilesUuid;
    }

    public void setVacancyFilesUuid(List<String> vacancyFilesUuid) {
        this.vacancyFilesUuid = vacancyFilesUuid;
    }

    /**
     * Default handler for this action. Checks if user is logged in.
     *
     * @return resolution: if user is not logged in we send him to login form
     *         else to create vacancy view
     */
    @DefaultHandler
    @DontValidate
    public Resolution createVacancy() {
        initVacancyByUUID();
        if (vacancy != null) {
            getContext().getRequest().setAttribute(CURRENT_CITY_ATTR, vacancy.getCity());
            updateCities();
        }
        return new ForwardResolution("/public/secured/createvacancy.jsp");
    }

    private void initVacancyByUUID() {
        String vacancyUuid;
        if ((vacancyUuid = getContext().getRequest().getParameter(VACANCY_UUID_PARAM)) != null) {
            vacancy = getVacancyService().getVacancy(vacancyUuid);
        }
        if (vacancy != null) {
            vacancyFilesUuid = getVacancyService().getVacancyFilesUuid(vacancy.getUuid());
        }
    }

    /**
     * Save resume handler
     *
     * @return Resolution - back to index.jsp page for now.
     */
    public Resolution saveVacancy() {
        //if uuid == null then we create resume else we update existing one
        vacancy.setAccount(accountService.getAccount(accountService.getUserName()));
        if (vacancy.getUuid() == null) {
            vacancy.setUuid(UUID.randomUUID().toString());
        }
        constructEntityFile(vacancy);
        vacancyService.saveVacancy(vacancy);
        return listVacancies();
    }

    /**
     * Handler for the uploading and constructing file for resume.
     *
     * @param vacancy Resume to which it belongs
     */
    private void constructEntityFile(Vacancy vacancy) {
        if (vacancyFile != null && vacancyFile.getFileBean() != null) {
            try {
                vacancyFile.setFile(IOUtils.toByteArray(vacancyFile.getFileBean().getInputStream()));
                vacancyFile.getFileBean().delete();
                vacancyFile.setUuid(UUID.randomUUID().toString());
                vacancy.setResumeFiles(Arrays.asList(vacancyFile));
            } catch (IOException e) {
                LOGGER.error(e);
            }
        }
    }

    @DontValidate
    public Resolution listVacancies() {
        if (accountService.getUserName() != null) {
            allVacancies = vacancyService.getVacancies(accountService.getAccount(accountService.getUserName()).getUuid());
        }
        return new ForwardResolution("/public/secured/listVacancies.jsp");
    }

    @DontValidate
    public Resolution deleteVacancyFile() {
        String vacancyFileUuid;
        if ((vacancyFileUuid = getContext().getRequest().getParameter(VACANCY_FILE_UUID_PARAM)) != null) {
            getVacancyService().deleteVacancyFile(vacancyFileUuid);
        }
        initVacancyByUUID();
        updateCities();
        return new ForwardResolution("/public/secured/createvacancy.jsp");
    }

    private List<City> cities;

    public List<City> getCities() {
        return cities;
    }

    private List<Vacancy> allVacancies;

    public List<Vacancy> getAllVacancies() {
        return allVacancies;
    }

    public void setAllVacancies(List<Vacancy> allVacancies) {
        this.allVacancies = allVacancies;
    }

    @DontValidate
    public Resolution updateCities() {
        cities = baseService.getCities(vacancy.getFkRegionId());
        return new ForwardResolution("/public/secured/citiesVacancyFragment.jsp");
    }

    public BaseService getBaseService() {
        return baseService;
    }

    public void setBaseService(BaseService baseService) {
        this.baseService = baseService;
    }

    public VacancyService getVacancyService() {
        return vacancyService;
    }

    public void setVacancyService(VacancyService vacancyService) {
        this.vacancyService = vacancyService;
    }

    public VacancyFile getVacancyFile() {
        return vacancyFile;
    }

    public void setVacancyFile(VacancyFile vacancyFile) {
        this.vacancyFile = vacancyFile;
    }
}
